package cn.hk.service;

import cn.HK.po.User;
import cn.HK.utils.MD5Util;
import cn.HK.utils.MapperUtil;
import cn.hk.mapper.LoginMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
public class LoginService {
    @Autowired(required = false)
    private LoginMapper loginMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;

    public String doLogin(User user) {
        //操作string类型 redis数据库
        ValueOperations<String, String>
                opsForString = redisTemplate.opsForValue();
        /*
            1.到数据库去校验,username password能不能查到一个user
            2.user判断是否为空
                2.1为空,说明用户名密码不对 返回空字符串/null
            3.登录成功,将数据放到redis一份
                3.1根据用户名生成 login_username的key值用来保存本次登录
                的ticket,判断他是否存在
                    * 不存在:目前是第一个使用过该账号登录的人 写2个key-value
                    * 存在:当前登录客户端不是第一个使用该账号,将之前的ticketOld拿出来,
                    删除,并且替换成本次的ticket
                3.2
                ticket:
                    唯一:不同用户 key值不同 username
                    顶替:相同用户,不同登录时间
                "EM_TICKET_"+系统时间+username
                userJson:
                    userJson字符串,将user对象按照读取数据
                    展示数据结构,构造json
            4.返回key值
         */
        user.setuPassword(MD5Util.md5(user.getuPassword()));
        User exist = loginMapper.selectExistByUnameAndUPassword(user);
        //判断
        if (exist == null) {
            return "";
        } else {
            //生成与用户名有关key值 loing_username
            String loginkey = "login_" + user.getuName();
            if (redisTemplate.hasKey(loginkey)) {
                //说明曾经有人登录过该账号,在数据库中删除上一次登陆的ticket
                String lastTicket = opsForString.get(loginkey);
                redisTemplate.delete(lastTicket);
            }

            //不同用户 key值不同 HK1_TICKET+时间戳+uName
            String ticket =
                    "HK1_TICKET"
                            +System.currentTimeMillis()
                            +user.getuName();
            //value
            exist.setuPassword(null);
            exist.setuName(exist.getuName());
            //将这个exist转化成json
            try {
                String userJson = MapperUtil.MP
                        .writeValueAsString(exist);
                //超时时间2小时
                opsForString.set(ticket, userJson,
                        2,
                        TimeUnit.HOURS);
                opsForString.set(loginkey, ticket,

                        2,
                        TimeUnit.HOURS);
                return ticket;
            } catch (Exception e) {
                e.printStackTrace();
                return "";
            }

        }
    }

    public User queryUserJson(String ticket) {
        //redis的key值已经获取了,ticket,只要从redis读取数据
        ValueOperations<String, String> opsForString
                = redisTemplate.opsForValue();
        /*
            从redis 获取该ticket的剩余时间,如果小于一小时
            重新设置超时时长,loginKey也要重新设置超时时长
         */
        //ticket 剩余时间
        Long leftTime
                = redisTemplate
                .getExpire(ticket, TimeUnit.MILLISECONDS);
        //保证 某些情况 loginkey超时时间和ticket一致
        String loginKey = "login_" + obtainUsername(ticket);
        //-2 表示过期了,剩余超时时间大于0
        if (leftTime < 1000 * 60 * 60) {
            //认为应该对其进行延长时间处理
            Boolean expire =
                    redisTemplate.expire(ticket, 2, TimeUnit.HOURS);
            if (expire) {
                redisTemplate.expire(loginKey, 2, TimeUnit.HOURS);
            }
        }
       if(StringUtils.isEmpty(opsForString.get(ticket))){
           return null;
       }else {
           User user = loginMapper.selectExistByUname(obtainUsername(ticket));
           user.setuPassword(null);
           return user;
       }
    }

    public String obtainUsername(String ticket) {
        //string的api从ticket解析username
        //HK1_TICKET1606889472682admin
        return ticket.substring(23);
    }
}
